<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    // 作用域 栈内存  执行上下文
    // 私有作用域和私有变量
    // 在形成全局作用域之后才有可能形成私有作用域，私有作用域是属于全局作用域的
    // 在函数执行的时候才会形成私有作用域

    // function fn(){

    // }

    // 函数的创建
    // 1、想开辟一个堆内存，生成一个16进制的空间地址
    // 2、把函数里的代码以字符串的格式存储进去
    // 3、把当前堆内存的空间地址返回到值存储区

    // 函数的执行
    // 1、开辟私有栈内存(形成私有作用域)为函数的执行提供环境
    // 2、形参赋值
    // 3、变量提升
    // 4、代码从上往下执行
    // 5、当前的栈内存(作用域)是否销毁

    // var a = 12;
    // function fn(num){
    //   console.log(num); // 10
    // }
    // fn(10);

    // 在私有作用域里边创建的变量就是私有变量
    // 在私有作用域里用var function let const 创建的变量就是私有变量
    // 函数的形参也是私有变量 (形参变量)

    // var a = 12; // 全局变量
    // let b = 12; // 全局变量
    // // 在同一个作用域下
    // function fn(){ // 全局变量

    //   var a = 13; // 私有变量
    //   let b = 12; // 私有变量
    //   console.log(a); // 13
    // }
    // fn();


    // var a = 10; // 全局
    // function fn(a){
    //   /* 
    //     a = 100  // 私有变量
    //    */
    //   console.log(a); // 100
    // }
    // fn(100);

    // 在使用一个变量的时候，先看自己有没有，如果自己有就使用自己的，如果自己没有，就往上一级作用域查找

    // 私有作用域里边可以使用外边的东西，但是外边不能使用私有作用域里边的东西

    // var a = 100; // 全局
    // function fn(){ // 全局
    // /* 

    //  */
    //   var b = 200; // 私有
    //   console.log(a); // 100
    // }
    // fn();
    // console.log(b); // b is not defined



    // var num = 100;
    // function fn(num){
    //   console.log(num++);
    // }
    // fn(num);
    // console.log(num);


    // var a = 10; // 11 // 全局
    // function fun() {

    //     a++; // 10
    //    };
    // fun();
    // console.log(a); // 11


      /* 
      num = 1 2
      s = 2
      fn = af0
      f = af1
       */
    let num = 1; 
    let s = 2;
    function fn() { // af0
    // fn的上一级作用域是全局
      /* 
      s = 1
      f = af1
       */
      num += 1;
      let s = 1;
      function f() { // af1
        /* 
        
         */
        console.log(num, s,x); // 2 1
      }
      return f; // af1
    }

    let f = fn(); // af1
    f();


    // 上一级作用域：函数在哪创建的
    // 那他的上一级做就是谁
    // 上一级作用域在函数创建的时候就已经确定好了


//     使用一个变量，先看自己有没有，如果自己有就使用自己的
// 如果自己没有就往上一级作用域查找，如果上一级还没有，
// 就往上一级的上一级查找，直到找到全局为止，如果全局还没有，那就
// 直接报错，这种一级一级往上查找的机制就是作用域链机制





  </script>
</body>

</html>